﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace SpeechToText.STT
{
    public class SoundDetector: IDisposable
    {
        Thread SecondThread;

        Microphone Microphone;
        Microphone Detector;
        Control Owner;

        public event RecordIsDoneMethod AsyncRecordDone;

        public bool isWorked { get; private set; }

        public SoundDetector(Control Owner)
        {
            this.Owner = Owner;
            Microphone = new Microphone(Owner);
            Detector = new Microphone(Owner);
        }
        ~SoundDetector()
        {
            Dispose();
        }

        public WavResource Record(double SoundVolume, int SilenceMilisec)
        {
            try
            {
                Microphone.ClearMicBufer();
                Detector.ClearMicBufer();

                WavResource W;
                int Silent = 0;

                Microphone.Start();
                do
                {
                    Microphone.ClearMicBufer();
                    W = Detector.RecordFor(1000);
                    Detector.ClearMicBufer();
                }
                while (!W.isNoisy(SoundVolume, 0.2));

                while (Silent < SilenceMilisec)
                {
                    if (Detector.RecordFor(50).isNoisy(SoundVolume, 0.2)) Silent = 0;
                    else Silent += 50;
                    Detector.ClearMicBufer();
                }

                Microphone.Stop();

                return Microphone.GetRecord();
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// Асинхроння запись звука при повышении заданной громкости
        /// </summary>
        /// <param name="SoundVolume">уровень громкости звука. вещественное значение от 0 до 1, при превышении начнется запись. Рекомендуется 0.15</param>
        /// <param name="SilenceMilisec">если после всплеска шума тишина продлится SilenceMilisec запись завершится</param>
        void AsyncRecord(double SoundVolume, int SilenceMilisec)
        {
            SecondThread = new Thread(delegate()
            {
                
                WavResource W = Record(SoundVolume, SilenceMilisec);

                if (isWorked)
                {
                    AsyncRecord(SoundVolume, SilenceMilisec);
                    if (AsyncRecordDone != null) Owner.Invoke(AsyncRecordDone, new object[] { W });                    
                }
            });

            SecondThread.Start();
        }

        public void Start(double SoundVolume, int SilenceMilisec)
        {
            isWorked = true;
            AsyncRecord(SoundVolume, SilenceMilisec); 
        }

        public void Stop()
        {
            isWorked = false;
        }

        public void Dispose()
        {
            if (isWorked) Stop();
            if (SecondThread != null) SecondThread.Abort();
            if (Microphone != null) Microphone.Dispose();
            if (Detector != null) Detector.Dispose();

            SecondThread = null;
            Microphone = null;
            Detector = null;
        }
    }
}
